package com.xbao.service.impl;

import com.xbao.core.component.page.Pagination;
import com.xbao.core.util.DateUtil;
import com.xbao.core.util.MyBeanUtil;
import com.xbao.dao.PeriodRecordExtraMapper;
import com.xbao.dao.PeriodRecordMapper;
import com.xbao.dao.PeriodRuleMapper;
import com.xbao.model.PeriodRecord;
import com.xbao.model.PeriodRecordComp;
import com.xbao.model.PeriodRecordExample;
import com.xbao.model.PeriodRuleItem;
import com.xbao.model.req.ClsReq;
import com.xbao.model.req.PeriodRecordReq;
import com.xbao.model.req.RecordQuery;
import com.xbao.model.vo.PeriodRecordTotalVo;
import com.xbao.model.vo.PeriodRecordVo;
import com.xbao.service.PeriodRecordService;
import com.xbao.service.PeriodRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by qingshengzheng on 18/10/11.
 */
@Service
public class PeriodRecordServiceImpl implements PeriodRecordService {
    @Autowired
    private PeriodRecordMapper recordMapper;
    @Autowired
    private PeriodRecordExtraMapper recordExtraMapper;

    @Resource
    private PeriodRuleService ruleService;


    @Override
    public void addPeriodRecord(PeriodRecordReq req) {
        recordMapper.insert(req);

    }

    @Override
    public List<PeriodRecordVo> queryPeriodRecordOfCls(Long cid) {
        PeriodRecordExample example = new PeriodRecordExample();
        PeriodRecordExample.Criteria criteria = example.createCriteria();
        criteria.andCidEqualTo(cid);
        List<PeriodRecord> records = recordMapper.selectByExample(example);
        List<PeriodRecordVo> vos = MyBeanUtil.copyList(records, PeriodRecordVo.class);
        return vos;
    }

    @Override
    public List<PeriodRecordVo> queryRecordOfCls(ClsReq clsReq) {
        PeriodRecordExample example = new PeriodRecordExample();
        PeriodRecordExample.Criteria criteria = example.createCriteria();
        if (clsReq.getId() != null) {
            criteria.andCidEqualTo(clsReq.getId());
        }
        List<PeriodRecord> records = recordMapper.selectByExample(example);
        List<PeriodRecordVo> vos = MyBeanUtil.copyList(records, PeriodRecordVo.class);
        return vos;
    }

    @Override
    public void deletePeriodRecordByClsId(Long cid) {
        recordMapper.deleteByPrimaryKey(cid);

    }

    @Override
    public void modifyPeriodRecord(PeriodRecordReq recordReq) {
        recordMapper.updateByPrimaryKeySelective(recordReq);
    }

    @Override
    public Long noFinishRecordCount(Long time, Long orgid) {
        return null;
    }

    @Override
    public Pagination<PeriodRecordVo> noFinishRecords(Long time, Long orgid) {
        return null;
    }


    @Override
    public void deletePeriodRecords(List<PeriodRecordReq> recordReqs) {

    }

    @Override
    public PeriodRecordVo nextPeriodRecordOfClss(Long cid, Long currenttime) {
     /*   PeriodRecordVo record = recordMapper.nextPeriodRecordOfClss(cid, System.currentTimeMillis());
        return record;*/
        return null;
    }

    @Override
    public PeriodRecordTotalVo queryPeriodREcordTotal(Long beginTime, Long endTime, Long orgid) {
        PeriodRecordTotalVo vo = new PeriodRecordTotalVo();
        Integer a = shouldFinishCount(beginTime, endTime, orgid);
        Integer b = shouldFinishCount(beginTime, endTime, orgid);
        vo.setPlanfinishPeriodCount(a);
        vo.setRealfinishPeriodCount(b);
        return vo;
    }

    @Override
    public Integer shouldFinishCount(Long beginTime, Long endTime, Long orgid) {
        Integer a = recordExtraMapper.shouldFinishCount(beginTime, endTime, orgid);
        return a;
    }

    @Override
    public Integer realFinishCount(Long beginTime, Long endTime, Long orgid) {
        Integer b = recordExtraMapper.shouldFinishCount(beginTime, endTime, orgid);
        return b;
    }

    @Override
    public List<PeriodRecordVo> getHistoryRecordsOfCls(RecordQuery query) {
        PeriodRecordExample example = new PeriodRecordExample();
        PeriodRecordExample.Criteria criteria = example.createCriteria();
        if (query.getCid() != null) {
            criteria.andCidEqualTo(query.getCid());
        }
        if (query.getBegintime() != null && query.getEndtime() != null) {
            criteria.andDaytimeBetween(query.getBegintime(), query.getEndtime());
        }
        List<PeriodRecord> records = recordMapper.selectByExample(example);
        List<PeriodRecordVo> vos = MyBeanUtil.copyList(records, PeriodRecordVo.class);
        return vos;

    }

    @Override
    public List<PeriodRecordVo> getHistoryRecordsOfStu(RecordQuery query) {
        List<PeriodRecord> records = recordExtraMapper.queryHistoryPeriodOfStu(query);
        List<PeriodRecordVo> vos = MyBeanUtil.copyList(records, PeriodRecordVo.class);
        return vos;
    }


    @Override
    public List<PeriodRecordVo> getNextRecordsOfStu(RecordQuery query) {
        return null;
    }


    @Override
    public List<PeriodRecordVo> getNextRecordsOfCls(RecordQuery query) {

        return null;
    }

    @Override
    public void checkRecord(PeriodRecordReq req) {
        this.modifyPeriodRecord(req);
        genNewRecordsFromRules(100,req.getRuleid());




    }

    public PeriodRecord getNextRecordFromRules(Long starttime, List<PeriodRuleItem> ruleItem) {

        List<PeriodRecord> records = new ArrayList<PeriodRecord>();
        for (PeriodRuleItem item : ruleItem) {
            records.add(getRecordFromRule(starttime, item));
        }
        List<PeriodRecordComp> coms = MyBeanUtil.copyList(records, PeriodRecordComp.class);
        Collections.sort(coms);
        return coms.get(0);
    }

    public Integer getNoCheckPeriodCount(Long  ruleid){
      Integer count=  recordExtraMapper.getNoCheckPeriodCount(ruleid);
      return count;
    }


    public void genNewRecordsFromRules(Integer count,Long ruleid){
        Integer remaincount=this.getNoCheckPeriodCount(ruleid);
        Long starttime=recordExtraMapper.selectMaxtimeByRuleId(ruleid);
        if(remaincount<5){
            List<PeriodRecord> records=getNextRecordsFromRules(starttime,count,ruleid);
            for(PeriodRecord periodRecord:records){
                recordMapper.insert(periodRecord);
            }
        }


    }






    public List<PeriodRecord> getNextRecordsFromRules(Long starttime, Integer count ,Long ruleid ) {
        List<PeriodRuleItem> ruleItem=ruleService.getItemsByRuleId(ruleid);
        List<PeriodRecordComp> result = new ArrayList<PeriodRecordComp>();
        List<PeriodRecordComp> crecords = new ArrayList<PeriodRecordComp>();
        while (true) {
            for (PeriodRuleItem item : ruleItem) {
                PeriodRecord record = getRecordFromRule(starttime, item);
                PeriodRecordComp comp = MyBeanUtil.copyProperties(record, PeriodRecordComp.class);
                comp.setRuleItem(item);
                crecords.add(comp);
            }
            Collections.sort(crecords);
            if (crecords.size()<count) {
              continue;
            } else {
                break;
            }
        }
        List<PeriodRecord> vs = new ArrayList<PeriodRecord>();
        for (PeriodRecordComp p : result) {
            vs.add(p);
        }
        return vs;
    }

    public PeriodRecord getRecordFromRule(Long starttime, PeriodRuleItem item) {
        Long ontime=null;
        switch (item.getRuletype()){
            case 1:
                ontime=DateUtil.getNextTimeEveryDay(starttime,item.getHour(),item.getMinute());
                break;
            case 2:
                ontime=DateUtil.getNextTimeEveryWeek(starttime, item.getNo(), item.getHour(), item.getMinute());
                break;
            case 3:
                ontime=DateUtil.getNextTimeEveryMonth(starttime,item.getNo(),item.getHour(),item.getMinute());
                break;
            default:
                break;
        }
        PeriodRecord record=new PeriodRecord();
        record.setOntime(ontime);
        record.setCid(item.getCid());
        record.setDurationtime(item.getDurationtime());
        record.setEndtime(ontime+item.getDurationtime());
        record.setComments("");
        record.setOrgid(item.getOrgid());
        return record;
    }


}
